﻿
#pragma once

#include <type_traits>
#include <utility>

namespace tools{
    namespace sfinae{

        template<class U, U u> struct Helper{};
        //------------------------------------------------------

        template<class C, class T, class U> struct Select { typedef void  Result; };
        template<class C, class T> struct Select<C,T,T>   { typedef C     Result; };

        //------------------------------------------------------
        template<class C, class T> struct Transform;
        template<class C, class R> struct Transform<C,R()>
        {
            typedef R(C::*Method)();
            typedef R(C::*CMethod)()const;
        };
        template<class C, class R,class A1> struct Transform<C,R(A1)> 
        {
            typedef R(C::*Method)(A1);
            typedef R(C::*CMethod)(A1)const;
        };
        template<class C, class R,class A1,class A2> struct Transform<C,R(A1,A2)>  
        {
            typedef R(C::*Method)(A1,A2);
            typedef R(C::*CMethod)(A1,A2)const;
        };
        template<class C, class R,class A1,class A2,class A3> struct Transform<C,R(A1,A2,A3)>
        {
            typedef R(C::*Method)(A1,A2,A3);
            typedef R(C::*CMethod)(A1,A2,A3)const;
        };
        //------------------------------------------------------

    }//namespace sfinae
}//namespace tools
